import base64
import json
import time
import requests

from DrissionPage import ChromiumPage, ChromiumOptions
from urllib.parse import urlparse, parse_qs

from app.chatgpt.utils import generate_code_challenge, generate_code_verifier
from app.utils.decorator import cache_func_data

from app.const import IS_LINUX

DefaultUserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"


class AuthBrowserios():

    def __init__(self):

        browser_path = "/usr/bin/google-chrome"
        options = ChromiumOptions()
        options.set_paths(browser_path=browser_path)

        if DefaultUserAgent:
            options.set_user_agent(DefaultUserAgent)

        arguments = [
            "--accept-lang=zh-CN,zh;q=0.9,en;q=0.8",
            "--no-first-run",
            "--force-color-profile=srgb",
            "--metrics-recording-only",
            "--password-store=basic",
            "--use-mock-keychain",
            "--export-tagged-pdf",
            "--no-default-browser-check",
            "--enable-features=NetworkService,NetworkServiceInProcess,LoadCryptoTokenExtension,PermuteTLSExtensions",
            "--disable-gpu",
            "--disable-infobars",  # 关闭菜单栏
            "--disable-extensions",
            "--disable-popup-blocking",
            "--disable-background-mode",
            "--disable-features=FlashDeprecationWarning,EnablePasswordsAccountStorage,PrivacySandboxSettings4",
            "--deny-permission-prompts",
            "--disable-suggestions-ui",
            "--hide-crash-restore-bubble",
            "--window-size=1920,1080",
        ]

        if IS_LINUX:
            arguments.append("--start-maximized")
            arguments.append("--no-sandbox")
        else:
            pass
            # arguments.append("--start-fullscreen")

        for argument in arguments:
            options.set_argument(argument)

        options.headless(False)

        self.driver = ChromiumPage(addr_or_opts=options)
        self.driver.set.cookies.clear()

    @cache_func_data(cache_time=900)
    def get_preauth_cookie(self):
        url = "https://publicapi.closeai.biz/auth/preauth"
        res = requests.get(url).json()
        return res["preauth_cookie"]

    def login(self, username, password):

        code_verifier = generate_code_verifier()
        code_challenge = generate_code_challenge(code_verifier)

        base_url = "https://auth0.openai.com/authorize?"
        client_info = {"version": "2.9.0-beta.0", "name": "Auth0.swift", "env": {"swift": "5.x", "macOS": "14.4"}}

        params = {
            "response_type": "code",
            # "state": generate_random_string(43),
            # "ios_device_id": "62BFAD6A-E648-4675-80AD-300268AD6010",
            "client_id": "pdlLIX2Y72MIl2rhLhTE9VV9bN905kBh",
            "code_challenge": code_challenge,
            "code_challenge_method": "S256",
            "scope": "openid%20email%20profile%20offline_access%20model.request%20model.read%20organization.read%20organization.write",
            "redirect_uri": "com.openai.chat://auth0.openai.com/ios/com.openai.chat/callback",
            "audience": "https://api.openai.com/v1",
            # "preauth_cookie": "62BFAD6A-E648-4675-80AD-300268AD6010:1724046725-VbsBdMxucRpMCKkLFZJbXaq5DJeADdMZsVco2A%252Bnj68%253D",
            "preauth_cookie": self.get_preauth_cookie(),
            "ios_app_version": "1723258889",
            "prompt": "login",
            "auth0Client": base64.b64encode(json.dumps(client_info).replace(" ", "").encode()).decode()
        }

        query_string = "&".join([f"{key}={value}" for key, value in params.items()])
        url = base_url + query_string
        # print(url)

        tab_id = self.driver.new_tab(url).tab_id
        tab = self.driver.get_tab(tab_id)
        tab.listen.start('com.openai.chat://auth0.openai.com/ios/com.openai.chat/callback')

        # tab.listen.start("auth0.openai.com")

        tab.wait.doc_loaded()
        username_ele = tab.ele('@name=username')
        username_ele.input(username)

        button_ele1 = tab.ele('css=button[name="action"][data-action-button-primary="true"]')
        button_ele1.click()

        time.sleep(1)
        password_ele = tab.ele('@name=password')
        password_ele.input(password)
        time.sleep(3)

        tab.run_js('document.querySelector("button[name=action]").removeAttribute("disabled")')
        button_ele2 = tab.ele('@name=action')
        print(button_ele2.html)
        button_ele2.click()

        tab.wait.load_start()
        time.sleep(5)
        res = tab.listen.wait()
        parsed_url = urlparse(res.url)

        query_params = parse_qs(parsed_url.query)
        code = query_params.get('code', [None])[0]

        print("code", code)
        print("code_verifier", code_verifier)


def get_token():
    url = 'https://auth0.openai.com/oauth/token'
    code = "C7W084buVmDd9YvQ67C9NfZ2us0l3Bu5NTE1oR1QErZiS"
    code_verifier = "bh2zBPax0UhTj0o8x1o8MbiqmOK7Td3ipKqZyWu1WIM"
    data = {
        'redirect_uri': 'com.openai.chat://auth0.openai.com/ios/com.openai.chat/callback',
        'grant_type': 'authorization_code',
        'client_id': 'pdlLIX2Y72MIl2rhLhTE9VV9bN905kBh',
        'code': code,
        'code_verifier': code_verifier,
    }
    resp = requests.post(url, json=data, allow_redirects=False)
    print(resp.json())
    '''
    {'access_token': 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik1UaEVOVUpHTkVNMVFURTRNMEZCTWpkQ05UZzVNRFUxUlRVd1FVSkRNRU13UmtGRVFrRXpSZyJ9.eyJzZXNzaW9uX2lkIjoiSDJrQnMza3FoNHNESE1FMThTUXdzcnlhakVNSTVXSm8iLCJodHRwczovL2FwaS5vcGVuYWkuY29tL3Byb2ZpbGUiOnsiZW1haWwiOiJoZXhpbmx1bkBpemt1bi5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZX0sImh0dHBzOi8vYXBpLm9wZW5haS5jb20vYXV0aCI6eyJwb2lkIjoib3JnLTBWU0pMQ2RrM1c2TlRjajVGeUJadG1CayIsInVzZXJfaWQiOiJ1c2VyLTZseGJFMnY3bkRhbEp5UXQ3MDhMZkRlbSJ9LCJpc3MiOiJodHRwczovL2F1dGgwLm9wZW5haS5jb20vIiwic3ViIjoiYXV0aDB8NjY4MzdjM2JhOTFmYjZhNDU4NjFhZjdmIiwiYXVkIjpbImh0dHBzOi8vYXBpLm9wZW5haS5jb20vdjEiLCJodHRwczovL29wZW5haS5vcGVuYWkuYXV0aDBhcHAuY29tL3VzZXJpbmZvIl0sImlhdCI6MTcyNjA2MzU0OCwiZXhwIjoxNzI2OTI3NTQ4LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG1vZGVsLnJlYWQgbW9kZWwucmVxdWVzdCBvcmdhbml6YXRpb24ucmVhZCBvcmdhbml6YXRpb24ud3JpdGUgb2ZmbGluZV9hY2Nlc3MiLCJhenAiOiJwZGxMSVgyWTcyTUlsMnJoTGhURTlWVjliTjkwNWtCaCJ9.P_tnus1dqf9co4b2yGFkkFzSsnU67YJB1vNZ3A_X0r39_48VNxJfIr_6XrXAlaB8NTpL3yZvW-t-yCsSq78wXmbbFV24DHKIouoqI5SaUL_eEyfYDSXO_xnbnXhxz40PY1sIiSPja_Y-Ia7JczP3XphEu5ry64tgaImwnIbKJVA3OetUmMY2I0fLTxbmZGEYjtuIynNdtNcH70wMyDjB_I6_znuLRZ32h02y8lVXZTzH-Jm112a7QZqjLzAanS3LLnLuj5Kvx2878GBBtojc53QfxIsSA6-ac6dpCPyXpWZFXOcri4qM9SGmeRD8K_zY0rHSlgd5sHOU-QjUIybB8A', 
    'refresh_token': 'c3g1fL8z9SY9SA7KBrc1Ym8QIgaY6mJTXRW09t0kqpBOE', 'id_token': 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik1UaEVOVUpHTkVNMVFURTRNMEZCTWpkQ05UZzVNRFUxUlRVd1FVSkRNRU13UmtGRVFrRXpSZyJ9.eyJodHRwczovL2FwaS5vcGVuYWkuY29tL2F1dGgiOnsiZ3JvdXBzIjpbXSwib3JnYW5pemF0aW9ucyI6W3siaWQiOiJvcmctMFZTSkxDZGszVzZOVGNqNUZ5Qlp0bUJrIiwiaXNfZGVmYXVsdCI6dHJ1ZSwicm9sZSI6Im93bmVyIiwidGl0bGUiOiJQZXJzb25hbCJ9XSwidXNlcl9pZCI6InVzZXItNmx4YkUydjduRGFsSnlRdDcwOExmRGVtIn0sIm5pY2tuYW1lIjoiaGV4aW5sdW4iLCJuYW1lIjoiaGV4aW5sdW5AaXprdW4uY29tIiwicGljdHVyZSI6Imh0dHBzOi8vcy5ncmF2YXRhci5jb20vYXZhdGFyLzIzMWVhYzgwODZhY2RlMjUxMmNjMDg2OWY2OWRlMTM4P3M9NDgwJnI9cGcmZD1odHRwcyUzQSUyRiUyRmNkbi5hdXRoMC5jb20lMkZhdmF0YXJzJTJGaGUucG5nIiwidXBkYXRlZF9hdCI6IjIwMjQtMDktMTFUMTQ6MDQ6MjcuMzIyWiIsImVtYWlsIjoiaGV4aW5sdW5AaXprdW4uY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImlzcyI6Imh0dHBzOi8vYXV0aDAub3BlbmFpLmNvbS8iLCJhdWQiOiJwZGxMSVgyWTcyTUlsMnJoTGhURTlWVjliTjkwNWtCaCIsImlhdCI6MTcyNjA2MzU0OCwiZXhwIjoxNzI2MDk5NTQ4LCJzdWIiOiJhdXRoMHw2NjgzN2MzYmE5MWZiNmE0NTg2MWFmN2YiLCJhdXRoX3RpbWUiOjE3MjYwNjM0NjcsInNpZCI6Ikgya0JzM2txaDRzREhNRTE4U1F3c3J5YWpFTUk1V0pvIn0.k2oebuOULaMd0JWLUaByvR8VWAQr6un8RzDA80F6uWmhXwQg1fxxHudMQN1pu3a7dlNHwbPN1jGM7Qrm8iiy45iGgftrvx-fXCrTkyUTKe43hFRW9v8XBSvE168BL8ACN29KruzKf2uSYnJLofu3U7tui9ZsJ7hF6xj1vuZcSbSJK5Ax4ffc8gGBv4-jgs_Et_AQ-Kmeo7RG75ghWJuMgZE22aAVAE_7tzrW5YN9_WTqANAgHPdiBEzZBsfjUKPnAD64cJ_qg8vf9ud8UmceLY8IhMKWio7TaU3O0zn9z0xGqRcezdS7BGyEQeXTnvrtX3jBfa5DKCi8MmFv4TWDVA', 'scope': 'openid profile email model.read model.request organization.read organization.write offline_access', 'expires_in': 864000, 'token_type': 'Bearer'}

    '''
